﻿namespace EFS.RC.CC.Tools.Schedulers
{
	/// <summary>
	/// OfficeConferenceWrapn
	/// </summary>
	internal class OfficeConferenceWrap : EFS.Common.Async.AsyncRoot
	{
		#region Composition

		// conference id 
		private EFS.RC.CC.Confereces.OfficeService officeServiceConference = null;

		// repeat
		private System.Threading.ManualResetEvent officeConferenceWrapEvent = null;

		#endregion

		#region Constructor
		
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="officeServiceConference"></param>
		public OfficeConferenceWrap(EFS.RC.CC.Confereces.OfficeService officeServiceConference)
		{
			// set
			EFS.Common.Verify.Reference(officeServiceConference, "officeServiceConference");

			// set
			this.officeServiceConference = officeServiceConference;

			// register terminated delegate
			this.officeServiceConference.AsinkTerminatedDelegate.Register(OnOfficeServiceConferenceTerminated);

			// make event
			officeConferenceWrapEvent = new System.Threading.ManualResetEvent(false);
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public override System.String Describe()
		{
			return System.String.Format("EFS.RC.CC.Tools.Schedulers.OfficeConferenceWrap [{0}]", officeServiceConference.Describe());
		}

		/// <summary>
		/// Begin startup
		/// </summary>
		public EFS.Common.Async.AsyncProcess Execute()
		{
			// log
			EFS.EventLog.Log.LogInfo("BeginStartup", this);

			// begin
			return BeginAsyncProcess2(ExecuteOfficeConferenceWrap, OnExecuteOfficeConferenceWrapComplete);
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Unhandled exception
		/// </summary>
		/// <param name="ex"></param>
		protected override void OnException(System.Exception ex)
		{
			// check
			EFS.Common.Verify.Reference(ex, "ex");

			// log
			EFS.EventLog.Log.LogException(ex, this);

			// SAL
			EFS.RC.CC.Tools.Loggers.SAL.Add(officeServiceConference.CustomerSession.ConversationGuid, "OnException", ex, this); 
		}

		#endregion

		#region Execute

		/// <summary>
		/// ExecuteOfficeConferenceWrap
		/// </summary>
		private void ExecuteOfficeConferenceWrap()
		{
			// log
			EFS.EventLog.Log.LogInfo("ExecuteOfficeConferenceWrap", this);

			// check wait event
			if (!officeConferenceWrapEvent.WaitOne(new System.TimeSpan(0, 0, EFS.RC.CC.Config.Settings.WrapConferenceAfterSeconds)))
			{
				// shut down
				officeServiceConference.BeginShutdown();
			}
		}

		/// <summary>
		/// Customer service office conference terminated
		/// </summary>
		/// <param name="agentHunter"></param>
		private void OnOfficeServiceConferenceTerminated(EFS.RC.CC.Confereces.OfficeService officeServiceConference)
		{
			// check
			EFS.Common.Verify.Reference(officeServiceConference, "officeServiceConference");

			// check mine
			EFS.Common.Verify.Condition(this.officeServiceConference.Equals(officeServiceConference), "Terminated conference is different");

			// set event
			officeConferenceWrapEvent.Set();
		
			// close
			BeginAsyncProcess2(CloseOfficeConferenceWrapEvent);
		}

		/// <summary>
		/// Close event
		/// </summary>
		private void CloseOfficeConferenceWrapEvent()
		{
			// set event
			officeConferenceWrapEvent.Close();
		}

		/// <summary>
		/// ExecuteOfficeConferenceWrap complete
		/// </summary>
		/// <param name="ar"></param>
		private void OnExecuteOfficeConferenceWrapComplete(EFS.Common.Async.AsyncProcess ap)
		{
			// log
			EFS.EventLog.Log.LogInfo("OnExecuteOfficeConferenceWrapComplete", this);

			try
			{
				// check
				ap.Throw();

				// log
				EFS.EventLog.Log.LogInfo("OnExecuteOfficeConferenceWrapComplete SUCCCESS", this);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion
	}
}
